﻿package com.goas3
{
	/**
	* ...
	* Classe para fazer login nos serviços google
	* @author Armando Leopoldo Keller
	* @version 0.0.1.Beta
	* @see http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html
	*/
	import flash.errors.IllegalOperationError;
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLVariables;
	import flash.net.URLRequestMethod;
	import flash.net.URLLoaderDataFormat;
	import com.goas3.events.LoginEvent;
	import flash.events.EventDispatcher;
	import flash.events.HTTPStatusEvent;
	import flash.errors.IOError;
	import flash.events.EventDispatcher;
	
	
	public class Login 
	{
		
		//Singleton
		private static var _instance:Login;
		
		// Constantes 
		public static const ACCOUNT_TYPE_GOOGLE:String           = "GOOGLE";
		public static const ACCOUNT_TYPE_HOSTED:String           = "HOSTED";
		public static const ACCOUNT_TYPE_HOSTED_OR_GOOGLE:String = "HOSTED_OR_GOOGLE";
		

		// Variaveis
		private var Urequest:URLRequest;
		private var Uloader:URLLoader;
		private var variaveis:URLVariables;
		private var disparador:EventDispatcher;
		private var _SID:String;
		private var _LSID:String;
		private var _AUTH:String;
		
		//Métodos
		/**
		 * Singleton
		 * @param	pvt  classe privada
		 */
		public function Login(pvt:Privada)
		{
		}
		public static function getInstance():Login
		{
			if (Login._instance == null)
			{
				Login._instance = new Login(new Privada());
				Login._instance.disparador = new EventDispatcher();
			}
			else
			{
				throw new IllegalOperationError("A Classe login só pode ser instanciada uma vez(Singleton)");
			}
			return Login._instance;
		}
		
		/**
		 * Faz o login nos serviços google
		 * @param	source        String Short string identifying your application, for logging purposes. This string should take the form:"companyName-applicationName-versionID".
		 * @param	Email         String User's full email address. It must include the domain (i.e. johndoe@gmail.com).
		 * @param	Passwd        String User's password.
		 * @param	service       String Name of the Google service you're requesting authorization for. Each service using the Authentication service is assigned a name value; for example, the name associated with Google Calendar is 'cl'. This parameter is required when accessing services based on Google data APIs; in this case, the generic service name "xapi" can be used. For specific service names, refer to the service documentation.
		 * @param	logintoken    String (optional) Token representing the specific CAPTCHA challenge. Google supplies this token and the CAPTCHA image URL in a login failed response with the error code "CaptchaRequired".
		 * @param	logincaptcha  String (optional) String entered by the user as an answer to a CAPTCHA challenge.
		 */
		public function loga(source:String, Email:String, Passwd:String, service:String = 'xapi',logintoken:String = null,logincaptcha:String=null):void
		{
			disparador.dispatchEvent(new LoginEvent(LoginEvent.LOGIN_INIT));
			if (!source)
			{
				disparador.dispatchEvent(new LoginEvent(LoginEvent.LOGIN_ERROR, "O parametro 'source' é obrigatorio"));
				throw new Error("O parametro 'source' é obrigatorio");
			}
			else if(!Email)
			{
				disparador.dispatchEvent(new LoginEvent(LoginEvent.LOGIN_ERROR, "O parametro 'Email' é obrigatorio"));
				throw new Error("O parametro 'Email' é obrigatorio");
			}
			else if (!Passwd)
			{
				disparador.dispatchEvent(new LoginEvent(LoginEvent.LOGIN_ERROR, "O parametro 'Passwd' é obrigatorio"));
				throw new Error("O parametro 'Passwd' é obrigatorio");
			}
			else
			{
				Urequest = new URLRequest("https://www.google.com/accounts/ClientLogin");
				Urequest.method = URLRequestMethod.POST;
				variaveis = new URLVariables();
				variaveis.source = source;
				variaveis.Email =  Email;
				variaveis.Passwd = Passwd;
				variaveis.service = service;
				if (logintoken) variaveis.logintoken = logintoken;
				if (logincaptcha) variaveis.logincaptcha = logincaptcha;
				
				Urequest.data = variaveis;
				
				Uloader = new URLLoader(Urequest);
				Uloader.dataFormat = URLLoaderDataFormat.VARIABLES;
				Uloader.addEventListener(Event.COMPLETE, recebeDados);
				Uloader.addEventListener(HTTPStatusEvent.HTTP_STATUS, statusHTTP);
				Uloader.load(Urequest);
			}
		}
		
		private function statusHTTP(e:HTTPStatusEvent):void
		{
			switch(e.status)
			{
				case 200:
					// foi
					break;
				case 403:
					disparador.dispatchEvent(new LoginEvent(LoginEvent.LOGIN_ERROR, "Access Forbidden"));
					break;
			}
		}
		
		private function recebeDados(e:Event = null):void
		{
			this._SID = e.target.data.SID.slice(0,e.target.data.SID.indexOf("LSID="));
			this._LSID = e.target.data.SID.slice(e.target.data.SID.indexOf("LSID=")+5,e.target.data.SID.indexOf("Auth="));
			this._AUTH = e.target.data.SID.slice(e.target.data.SID.indexOf("Auth=",0)+5,e.target.data.SID.length);
			disparador.dispatchEvent(new LoginEvent(LoginEvent.LOGIN_COMPLETE));
		}
		
		public function addEventListener(type:String,listener:Function,useCapture:Boolean = false,priority:int = 0,useWeakReference:Boolean = false):void
		{
			disparador.addEventListener(type, listener, useCapture, priority, useWeakReference);
		}
		
		// Getters
		public function get AUTH():String
		{
			return this._AUTH;
		}
		public function get SID():String
		{
			return this._SID;
		}
		public function get LSID():String
		{
			return this._LSID;
		}
	}
}
class Privada
{
	public function Privada()
	{
	}
}